import { customAlphabet } from "nanoid";
import { PrismaClient, table_info } from "@prisma/client";
import { Prisma } from ".prisma/client";

type ModelName = Prisma.ModelName;

const prisma = new PrismaClient();

/**
 *  @class 创建id
 *  @deprecated
 */
export class CreateId {
   static #nanoid = customAlphabet("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ", 29);
   /**
    * @function 在table_info中注册表信息
    * @param tableName  表名
    * @param total      当前表数据总数
    */
   static async #registerTable(tableName: ModelName | string, total?: number) {
      if (typeof total != "number") {
         const res = (await prisma.$queryRawUnsafe(`SELECT count(*) FROM ${tableName}`)) as Array<any>;
         total = Number(res[0]["count(*)"]);
      }

      let tableInfo = await prisma.table_info.findFirst({ where: { table_name: "table_info" } });

      if (!tableInfo) {
         const idPrefix = this.#nanoid();

         tableInfo = await prisma.table_info.create({
            data: {
               table_name: "table_info",
               id: idPrefix + "00",
               id_prefix: idPrefix,
               next_index: 1,
               total: 1
            }
         });
      }

      const idPrefix = this.#nanoid();

      // 在 table_info 表中创建信息的记录
      const newTable = await prisma.table_info.create({
         data: {
            id: tableInfo.id_prefix + (tableInfo.next_index % 100).toString().padStart(2, "0"),
            id_prefix: idPrefix,
            table_name: tableName,
            next_index: 0,
            total: total + 1
         }
      });

      // 更新 table_info 表中关于 table_info 的记录
      await prisma.table_info.update({
         where: { id: tableInfo.id },
         data: { next_index: tableInfo.next_index + 1, total: tableInfo.total + 1 }
      });

      return newTable;
   }

   /**
    * @function 生成id
    * @param tableName  要插入的 id 的表名称
    */
   static async One(tableName: ModelName): Promise<string> {
      // 查询当前表的数据量
      const res = (await prisma.$queryRawUnsafe(`SELECT count(*) FROM ${tableName}`)) as Array<any>;
      const total = Number(res[0]["count(*)"]);

      let index = 0; // 初始化序号位 0

      // 查询在 table_info 表中记录的 id 前缀
      let tableInfo = await prisma.table_info.findFirst({ where: { table_name: tableName } });

      let idPrefix = "";

      // 如果查询不到表格信息，则在 table_info 中注册
      if (tableInfo == null) tableInfo = await this.#registerTable(tableName, total);

      index = tableInfo.next_index;
      idPrefix = tableInfo.id_prefix;

      // 当序号超出两位数时，生成新的 id 前缀
      if (index == 100) idPrefix = this.#nanoid();

      await prisma.table_info.update({
         where: { id: tableInfo.id },
         data: { id_prefix: idPrefix, next_index: index + 1, total: total + 1 }
      });

      let indexString = (index % 100).toString().padStart(2, "0"); // 将序号转为字符串

      return idPrefix + indexString;
   }

   /**
    * @function 回退一个id
    * @param tableName 要回退的 id 的表名称
    */
   static async FallbackOne(tableName: ModelName) {}

   /**
    * @name 生成多个id
    * @param tableName  表名称
    * @param num        生成id数量 2-999
    */
   static async multiple(tableName: ModelName, num: number): Promise<Array<string>> {
      // 查看 number 范围

      // 查询当前表的数据量
      const res = (await prisma.$queryRawUnsafe(`SELECT count(*) FROM ${tableName}`)) as Array<any>;

      const total = Number(res[0]["count(*)"]);

      let index = 0; // 初始化序号位 0
      if (total != 0) index = total % 100; // 当存在数据量时，简化为 2 位数序号

      let tableInfo = await prisma.table_info.findFirst({ where: { table_name: tableName } });

      // 获取不到信息时
      if (tableInfo == null) tableInfo = await this.#registerTable(tableName, total);

      let ids: string[] = [];

      for (let i = tableInfo.next_index; i < num + tableInfo.next_index; i++) {
         // 当序号超过99时，生成新的 id 前缀
         if (i % 100 === 0) tableInfo.id_prefix = this.#nanoid();

         let idPrefix = tableInfo.id_prefix;
         let indexString = (i % 100).toString().padStart(2, "0"); // 将序号转为字符串
         ids.push(idPrefix + indexString);
      }

      // 更新next_index
      await prisma.table_info.update({
         where: { id: tableInfo.id },
         data: {
            id_prefix: tableInfo.id_prefix,
            next_index: (tableInfo.next_index + num) % 100,
            total: tableInfo.total + num
         }
      });

      return ids;
   }

   /**
    * @function 为表内的条目生成id
    * @param tableName 表名称
    * @param id 条目 id
    * @returns
    */
   static async OneValueId(tableName: ModelName, id: string) {
      // 查询指定指定表中的当前行数据
      const lineValue = ((await prisma.$queryRawUnsafe(`SELECT * FROM ${tableName} WHERE id='${id}';`)) as any[])[0];
      const valueName = tableName + "_" + lineValue.code;
      const value: any[] | null = lineValue.value;

      let index = 0; // 初始化序号位 0
      let total = 0; // 初始化总数为 0
      if (value) {
         index = value.length - 1;
         total = value.length;
      }

      // 查询在 table_info 表中记录的 id 前缀
      let tableInfo = await prisma.table_info.findFirst({ where: { table_name: valueName } });

      let idPrefix = "";

      // 如果查询不到表格信息，则在 table_info 中注册
      if (tableInfo == null) tableInfo = await this.#registerTable(valueName, total);

      index = tableInfo.next_index;
      idPrefix = tableInfo.id_prefix;

      // 当序号超出两位数时，生成新的 id 前缀
      if (index == 100) idPrefix = this.#nanoid();

      await prisma.table_info.update({
         where: { id: tableInfo.id },
         data: { id_prefix: idPrefix, next_index: index + 1, total: total + 1 }
      });

      let indexString = (index % 100).toString().padStart(2, "0"); // 将序号转为字符串

      return idPrefix + indexString;
   }
}
